package com.bgds.sys.api.feign;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bgds.sys.api.bean.mos.dto.MeasurementDto;
import com.bgds.sys.api.bean.mos.dto.VibdatasDto;
import com.bgds.sys.common.exception.BusinessException;
import com.bgds.sys.common.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author lj
 * 容知接口
 */
@Slf4j
public class MosHttpClient {


    public static final String TIMESTAMP_KEY = "Time";
    public static final String REQUEST_ID = "RequestId";
    public static final String APP_KEY = "AppKey";
    public static final String APP_KEY_VALUE = "10001";
    public static final String SIGN = "Sign";
    public static final String SECRET = "M/vkPOWXgBa7GnRd73t7j+jsKfbZtb+f";
    private static final String HTTP_URL = "http://223.244.82.230:8125/api/EPMMOS/V2/";
    private static final String HTTP_URL_NO = "http://223.244.82.230:8125/api/EPMMOS/";
    private static OkHttpClient client;

    /**
     * 单例模式  获取类实例
     *
     * @return client
     */
    private static OkHttpClient getInstance() {
        if (client == null) {
            synchronized (OkHttpClient.class) {
                if (client == null) {
                    client = new OkHttpClient.Builder()
                            .connectTimeout(5, TimeUnit.SECONDS)
                            .readTimeout(7, TimeUnit.SECONDS)
                            .build();
                }
            }
        }
        return client;
    }


    /**
     * 把数组所有元素排序，并按照“参数=参数值”的模式用“&”字符拼接成字符串
     *
     * @param params 需要排序并参与字符拼接的参数组
     * @return 拼接后字符串
     */
    public static String createLinkString(Map<String, String> params) {

        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key);

            // 拼接时，不包括最后一个&字符
            if (i == keys.size() - 1) {
                sb.append(key).append("=").append(value);
            } else {
                sb.append(key).append("=").append(value).append("&");
            }
        }

        return sb.toString();
    }

    /**
     * sha256_HMAC加密
     *
     * @param message 消息
     * @param secret  秘钥
     * @return 加密后字符串
     */
    public static String sha256Hmac(String message, String secret) {
        String hash = "";
        try {
            Mac mac = Mac.getInstance("HmacSHA256");
            SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
            mac.init(secretKey);
            byte[] bytes = mac.doFinal(message.getBytes());
            hash = byteArrayToHexString(bytes);
        } catch (Exception e) {
            throw new BusinessException(500, "HmacSHA256加密失败");
        }
        return hash;
    }

    public static String byteArrayToHexString(byte[] bArr) {
        StringBuffer sb = new StringBuffer(bArr.length);
        String sTmp;

        for (int i = 0; i < bArr.length; i++) {
            sTmp = Integer.toHexString(0xFF & bArr[i]);
            if (sTmp.length() < 2) {
                sb.append(0);
                sb.append(sTmp.toUpperCase());
            }
        }

        return sb.toString();
    }

    /**
     * 处理get请求
     *
     * @param params 参数集合
     * @param api    请求api
     * @return
     * @throws Exception
     */
    public static String doGet(Map<String, String> params, String api) throws Exception {
        String time = DateUtils.convertDate2String("yyyy-MM-dd HH:mm:ss", new Date());
        StringBuilder sb = new StringBuilder();
        sb.append(time).append(APP_KEY_VALUE).append(UUID.randomUUID().toString());
        String createLinkString = createLinkString(params);
        String url = HTTP_URL + api + "?" + createLinkString;
        log.info(url);
        Request request = new Request.Builder().
                addHeader(TIMESTAMP_KEY, time).
                addHeader(APP_KEY, APP_KEY_VALUE).
                addHeader(REQUEST_ID, UUID.randomUUID().toString()).
                addHeader(SIGN, sha256Hmac(sb.toString(), SECRET))
                .url(url).get().build();
        Response response = getInstance().newCall(request).execute();
        return response.body().string();
    }

    /**
     * 处理get请求
     *
     * @param api
     * @return
     * @throws Exception
     */
    public static String requestGet(Map<String, String> params, String api) throws Exception {
        String time = DateUtils.convertDate2String("yyyy-MM-dd HH:mm:ss", new Date());
        StringBuilder sb = new StringBuilder();
        sb.append(time).append(APP_KEY_VALUE).append(UUID.randomUUID().toString());
        String createLinkString = "";
        if (params != null) {
            createLinkString = createLinkString(params);
        }

        String url = HTTP_URL_NO + api + "?" + createLinkString;
        log.info(url);
        Request request = new Request.Builder().
                addHeader(TIMESTAMP_KEY, time).
                addHeader(APP_KEY, APP_KEY_VALUE).
                addHeader(REQUEST_ID, UUID.randomUUID().toString()).
                addHeader(SIGN, sha256Hmac(sb.toString(), SECRET))
                .url(url).get().build();
        Response response = getInstance().newCall(request).execute();
        return response.body().string();
    }

    public static void main(String[] args) throws Exception {
        String time = DateUtils.convertDate2String("yyyy-MM-dd HH:mm:ss", new Date());
        String uuid = UUID.randomUUID().toString();
        StringBuilder sb = new StringBuilder();
        sb.append(APP_KEY_VALUE).append(time).append(uuid);
        Map<String, String> params = new HashMap<>(3);
        params.put("MinDate", "2020-08-28 00:00:00");
        params.put("MaxDate", "2020-08-28 22:00:00");
        String createLinkString = createLinkString(params);
        String url = HTTP_URL_NO + "GetMeasurementByPeriod/21069b5c-1361-40d3-bc3c-4f09a69e5001?" + createLinkString;
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder().
                addHeader(TIMESTAMP_KEY, time).
                addHeader(APP_KEY, APP_KEY_VALUE).
                addHeader(REQUEST_ID, UUID.randomUUID().toString()).
                addHeader(SIGN, sha256Hmac(sb.toString(), SECRET))
                .url(url).get().build();
        Response response = client.newCall(request).execute();
        String result = response.body().string();
        //371b99f4-eeaa-4ccd-a283-1cd2a4600b3f 监测点
        MeasurementDto measurementDto = JSON.parseObject(result, MeasurementDto.class);
        log.info("采样数据：{}", measurementDto);
    }

}
